package simulacao;

import javafx.scene.Group;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import simulacao.util.*;
import simulacao.cenario.*;
import simulacao.modelo.pistas.PistaCircuito;
import simulacao.modelo.pistas.PistaSemiOval;
import java.lang.Integer;
import javafx.util.Math;
import simulacao.Config;
import javafx.scene.text.TextAlignment;
import javafx.scene.CustomNode;
import javafx.scene.Node;
import javafx.scene.control.ListView;
import simulacao.SimulationCore;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Rectangle;
import simulacao.modelo.veiculos.Veiculo;
import simulacao.util.estruturas.VetorColisao;

var cenarioPistaSemiOval: Cenario = Cenario {
    icone: Util.makeImage("botoes/pista-semioval80-60")
    idCenario: 0
    pista: PistaSemiOval {}
    quantidadeCaminhoes: 2
    quantidadeCarros: 3
    visible: true
}

var cenarioPistaCircuito: Cenario = Cenario {
    icone: Util.makeImage("botoes/pista-circuito80-60")
    idCenario: 1
    pista: PistaCircuito {}
    quantidadeCaminhoes: 4
    quantidadeCarros: 9
    visible: false
}

public-read def cenarios: Cenario[] = [cenarioPistaSemiOval, cenarioPistaCircuito];

public function setarCenarioCorrente(idNovoCenario : Integer){
    if (idNovoCenario >= 0 and idNovoCenario < sizeof cenarios) {

        cenarioCorrente.fadeOut();
        cenarioCorrente.visible = false;
        cenarioCorrente.reset();

        SimulationCore.contadorGeral = 0;
        cenarioCorrente = cenarios[idNovoCenario];

        cenarioCorrente.fadeIn();
        cenarioCorrente.visible = true;
        cenarioCorrente.playFromStart();
    }

    SimulationCore.vetorDeAntecipacaoDeColisao = VetorColisao.inicializa(cenarioCorrente.veiculos.size());
}

public var cenarioCorrente: Cenario = cenarios[0];

public var simulacaoExecutando: Boolean = false;

var playImage = Util.makeImage("botoes/play");
var pauseImage = Util.makeImage("botoes/pause");

var listViewVeiculos : ListView;

var toolTip : ToolTip = ToolTip{};

public class SimulationView extends CustomNode {

    public var simulationBoard: Group = Group {
                content: [

                    //Imagem de fundo
                    ImageView {
                        image: Util.makeImage("botoes/car-bg")
                        fitWidth: Config.SCREEN_WIDTH,
                        fitHeight: Config.SCREEN_HEIGHT
                    },

                    //Botao de Play/Pause
                    ImageView {
                        image: bind if (simulacaoExecutando) then pauseImage else playImage
                        layoutX: Config.SCREEN_WIDTH - 100
                        layoutY: 30
                        focusTraversable: true
                        onMousePressed: function (ev: MouseEvent) {
                            SimulationCore.alternarPlayPause();
                        }
                    },

                    // List para definir qual veiculo esta selecionado
                    listViewVeiculos = ListView {
                        items: bind for (veiculo in cenarioCorrente.veiculos) veiculo
                        layoutX: Config.SCREEN_WIDTH - 430
                        layoutY: 30
                        width:  120
                        height: 160
                        onMouseClicked: function (ev: MouseEvent){
                            cenarioCorrente.veiculoSelecionado = listViewVeiculos.selectedItem as Veiculo
                        }
                    },

                    //Botao para trocar de faixa o Veiculo Selecionado
                    Button {
                        text: "Forçar Troca de Faixa"
                        layoutX: Config.SCREEN_WIDTH - 300
                        layoutY: 30
                        width: 160
                        height: 25
                        action: function () {
                            cenarioCorrente.veiculoSelecionado.trocarDeFaixaDeRodagem();
                        }
                    },
                    
                    
                    //*******************************************************************************************************************
                    //*******************************************************************************************************************
                    
                    Group {
                        content: [
                            //Botao para diminuir a velocidade do Veiculo Selecionado
                            Button {
                                text: "-5"
                                width: 30
                                height: 25
                                action: function () {
                                    cenarioCorrente.veiculoSelecionado.velocidadeEmPistaLivre -= 5;
                                    cenarioCorrente.veiculoSelecionado.velocidadeAlvo -= 5;
                                    cenarioCorrente.veiculoSelecionado.setVelocidadeEmSubida(cenarioCorrente.veiculoSelecionado.velocidadeEmPistaLivre);
                                }
                            },
                            //Botao para aumentar a velocidade do Veiculo Selecionado
                            Button {
                                text: "+5"
                                layoutX: 130
                                width: 30
                                height: 25
                                action: function () {
                                    cenarioCorrente.veiculoSelecionado.velocidadeEmPistaLivre += 5;
                                    cenarioCorrente.veiculoSelecionado.velocidadeAlvo += 5;
                                    cenarioCorrente.veiculoSelecionado.setVelocidadeEmSubida(cenarioCorrente.veiculoSelecionado.velocidadeEmPistaLivre);
                                }
                            },
                            //Veolocidade em pista livre do Veiculo Selecionado
                            Text {
                                layoutX: 50
                                layoutY: 20
                                content: bind "{Math.round(cenarioCorrente.veiculoSelecionado.velocidadeEmPistaLivre)}Km/h";
                                font: Font {size: 18}
                                fill: Color.WHITE
                                textAlignment:TextAlignment.CENTER
                            },
                            Rectangle{
                                height:25
                                width:160
                                fill:Color.TRANSPARENT
                                visible: true
                            }
                        ]

                        layoutX: Config.SCREEN_WIDTH - 300
                        layoutY: 90

                        onMouseEntered: function(evt: MouseEvent){
                            toolTip.x = evt.sceneX;
                            toolTip.y = evt.sceneY;
                            toolTip.texto = "Velocidade em Pista Livre";
                            toolTip.visivel = true;
                        }
                        onMouseExited: function(evt: MouseEvent){
                            toolTip.visivel = false;
                        }
                    },


                    //*******************************************************************************************************************
                    //*******************************************************************************************************************


                    //Indice de Agressividade do Veiculo Selecionado
                    Group {
                        content: [
                            //Botao para aumentar o indice de agressividade do Veiculo Selecionado
                            Button {
                                text: "-1"
                                width: 30
                                height: 25
                                action: function () {
                                    cenarioCorrente.veiculoSelecionado.indiceDeAgressividade--;
                                }
                            },
                            //Botao para diminuir o indice de agressividade do Veiculo Selecionado
                            Button {
                                text: "+1"
                                layoutX: 130
                                width: 30
                                height: 25
                                action: function () {
                                    cenarioCorrente.veiculoSelecionado.indiceDeAgressividade++;
                                }
                            },
                            Text {
                                layoutX: 70
                                layoutY: 20
                                content: bind "{cenarioCorrente.veiculoSelecionado.indiceDeAgressividade}";
                                font: Font {size: 18}
                                fill: Color.WHITE
                                textAlignment:TextAlignment.CENTER

                            },
                            Rectangle{
                                height:25
                                width:160
                                fill:Color.TRANSPARENT
                                visible: true
                            }
                        ]
                        
                        layoutX: Config.SCREEN_WIDTH - 300
                        layoutY: 60

                        onMouseEntered: function(evt: MouseEvent){
                            toolTip.x = evt.sceneX;
                            toolTip.y = evt.sceneY;
                            toolTip.texto = "Índice de Agressividade";
                            toolTip.visivel = true;
                        }
                        onMouseExited: function(evt: MouseEvent){
                            toolTip.visivel = false;
                        }
                    },

                    //*******************************************************************************************************************
                    //*******************************************************************************************************************

                    //Velocidade atual do veiculo selecionado
                    Group {
                        content: [
                            Text {
                                layoutX: 20
                                content: bind "{Math.round(cenarioCorrente.veiculoSelecionado.velocidadeAtual)}Km/h";
                                font: Font.font ("Verdana", FontWeight.BOLD, 28)
                                fill: Color.YELLOW
                                textAlignment:TextAlignment.CENTER

                            },
                            Rectangle{
                                height:40
                                width:160
                                fill:Color.TRANSPARENT
                                visible: true
                            }
                        ]

                        layoutX: Config.SCREEN_WIDTH - 300
                        layoutY: 170

                        onMouseEntered: function(evt: MouseEvent){
                            toolTip.x = evt.sceneX;
                            toolTip.y = evt.sceneY;
                            toolTip.texto = "Velocidade Atual";
                            toolTip.visivel = true;
                        }
                        onMouseExited: function(evt: MouseEvent){
                            toolTip.visivel = false;
                        }
                    },


                    //*******************************************************************************************************************
                    //*******************************************************************************************************************

                    Group {
                        content: [
                            //Botao para adicionar um veiculo
                            Button {
                                text: "Adicionar Veículo"
                                width: 160
                                height: 25
                                action: function () {
                                    cenarioCorrente.adicionarVeiculoAleatorioAposInicioDaSimulacao();
                                }
                            },

                            //Botao para remover um veiculo
                            Button {
                                text: "Remover Veículo"
                                layoutY: 30
                                width: 160
                                height: 25
                                action: function () {
                                    cenarioCorrente.removerVeiculoSelecionado();
                                }
                            },

                            //Botao para exibir/ocultar bounding boxes de colisao frontal
                            Button {
                                text: bind if(Config.EXIBIR_BOUNDING_BOX_DETECTAR_COLISAO_FRONTAL) "Ocultar Colisões Frontais" else "Exibir Colisões Frontais"
                                layoutY: 60
                                width: 160
                                height: 25
                                action: function () {
                                    Config.EXIBIR_BOUNDING_BOX_DETECTAR_COLISAO_FRONTAL = not Config.EXIBIR_BOUNDING_BOX_DETECTAR_COLISAO_FRONTAL;
                                }
                            },

                            //Botao para exibir/ocultar bounding boxes de colisao lateral
                            Button {
                                text: bind if(Config.EXIBIR_BOUNDING_BOX_DETECTAR_COLISAO_LATERAL) "Ocultar Colisões Laterais" else "Exibir Colisões Laterais"
                                layoutY: 90
                                width: 160
                                height: 25
                                action: function () {
                                    Config.EXIBIR_BOUNDING_BOX_DETECTAR_COLISAO_LATERAL = not Config.EXIBIR_BOUNDING_BOX_DETECTAR_COLISAO_LATERAL;
                                }
                            },

                            //Botao para exibir/ocultar bounding boxes dos veiculos
                            Button {
                                text: bind if(Config.EXIBIR_BOUNDING_BOX_VEICULO) "Ocultar Bounding Boxes" else "Exibir Bounding Boxes"
                                layoutY: 120
                                width: 160
                                height: 25
                                action: function () {
                                    Config.EXIBIR_BOUNDING_BOX_VEICULO = not Config.EXIBIR_BOUNDING_BOX_VEICULO;
                                }
                            }
                        ]

                        layoutX: Config.SCREEN_WIDTH - 600
                        layoutY: 30
                    },

                    //*******************************************************************************************************************
                    //*******************************************************************************************************************

                    // Cenarios
                    cenarios,

                    // Retangulo de mascaramento do inicio da simulação
                    Rectangle {
                        height: Config.SCREEN_HEIGHT - 210
                        width: Config.SCREEN_WIDTH
                        layoutX: 0
                        layoutY: 210
                        fill: Color.BLACK
                        opacity: 0.95
                        visible: bind SimulationCore.contadorGeral < 40
                    },

                    // Texto de ajuste do posicionamento dos veiculos
                    Text {
                        layoutX: 150
                        layoutY: Config.SCREEN_HEIGHT / 2
                        font: Font {size: 40}
                        textAlignment: TextAlignment.CENTER
                        fill: Color.WHITE
                        content: "Aguarde... \nAjustando posicionamento dos Veículos..."
                        visible: bind SimulationCore.contadorGeral < 40 and 
                                      SimulationCore.contadorGeral > 0  and
                                      SimulationCore.contadorGeral mod 10 <= 5
                    },

                    // Texto de créditos
                    Text {
                        layoutX: 150
                        layoutY: Config.SCREEN_HEIGHT / 2
                        font: Font {size: 20}
                        textAlignment: TextAlignment.CENTER
                        fill: Color.WHITE
                        content:"-------------------------------------------------------------- \n"
                                "Bem-vindo ao projeto Simulador de Trânsito \n "
                                "--------------------------------------------------------------  \n \n"
                                "Este projeto foi desenvolvido como parte do meu trabalho de conclusão de curso de \n "
                                "graduação em Ciência da Computação na Universidade Federal Fluminense. \n \n"
                                "Autor: Marcello Willians Messina Ribeiro\n "
                                "Orientador: Mauricio Kischinhevsky \n "
                                "Contato: marcellowmr@yahoo.com.br \n \n"
                                "Niterói - Fevereiro de 2010"
                        visible: bind SimulationCore.contadorGeral < 40 and
                                      SimulationCore.contadorGeral == 0
                    },

                    // Botoes para os cenarios
                    for (i in [0..sizeof (cenarios) - 1]) BotaoTrocarCenario {
                            indice: cenarios[i].idCenario,
                            selecionado: bind cenarios[i].visible,
                            imagem: cenarios[i].icone
                    },

                    //toolTip
                    toolTip,
                ]
            }

override public function create(): Node {

//  Descomente a linha abaixo para salvar o log da simulação em arquivo
//        Main.threadEscrita.init();
        return simulationBoard;
    }

}
